<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 流年 <liu21st@gmail.com>
// +----------------------------------------------------------------------

// 应用公共文件
use \think\facade\Env,
    \think\File,
    \OSS\OssClient,
    \Grafika\Grafika,
    \think\facade\Log,
    \Endroid\QrCode\QrCode;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;

define('BUTLER_ID', 4);  //管家身份ID;

/**
 * 获取图片地址
 * @param $path
 * @param int $expired 签名过期时间秒
 * @return string
 */
function get_img_url($path, $expired = 3600)
{
    $accessKeyId = Env::get('aliyun.oss_access_id');
    $accessKeySecret = Env::get('aliyun.oss_access_key');
    $endpoint = Env::get('aliyun.oss_endpoint');
    $bucket = Env::get('aliyun.oss_bucket');
    $myOssUrl = Env::get('aliyun.oss_url');
    $url = '';
    //var_dump($accessKeyId,$accessKeySecret,$endpoint,$bucket);die;
    try {
        $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint);
        $url = $ossClient->signUrl($bucket, $path, $expired);
        $url = str_replace(str_replace("http://", "http://$bucket.", $endpoint), $myOssUrl, $url);
    } catch (\OSS\Core\OssException $e) {
        Log::info("oss signUrl path={$path} error={$e->getMessage()}");
    }
    return $url;
}

/**
 * 获取缩略图片地址
 * @param $path
 * @param int $expired 签名过期时间秒
 * @return string
 */
function get_thumb_img_url($path, $expired = 60)
{
    $accessKeyId = Env::get('aliyun.oss_access_id');
    $accessKeySecret = Env::get('aliyun.oss_access_key');
    $endpoint = Env::get('aliyun.oss_endpoint');
    $bucket = Env::get('aliyun.oss_bucket');
    $myOssUrl = Env::get('aliyun.oss_url');
    $url = '';
    $pos = strrpos($path, '.');
    $path = substr($path, 0, $pos) . 'sm' . substr($path, $pos);
    //var_dump($accessKeyId,$accessKeySecret,$endpoint,$bucket);die;
    try {
        $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint);
        $url = $ossClient->signUrl($bucket, $path, $expired);
        $url = str_replace(str_replace("http://", "http://$bucket.", $endpoint), $myOssUrl, $url);
    } catch (\OSS\Core\OssException $e) {
        Log::info("oss signUrl path={$path} error={$e->getMessage()}");
    }
    return $url;
}

function get_extension($file)
{
    return substr(strrchr($file, '.'), 1);
}

/**
 * 创建目录
 * @param $dirName
 * @param int $rights
 */
function mmkdir($dirName, $rights = 0777)
{
    if (!is_dir($dirName)) {
        mmkdir(dirname($dirName));
    }
    @mkdir($dirName);
    @chmod($dirName, $rights);
}


/**
 * 生成oss文件上传相关
 * @param string $source 源文件名
 * @return array
 */
function generate_oss_info($source = '')
{
    $now = time();
    $name = md5($now . uniqid() . $source);
    $file_dir = date('Y/m/d', $now);
    $ext = get_extension($source);
    return array(
        'name' => $name,
        'file_name' => "{$name}.$ext",
        'file_dir' => $file_dir,
        'local_file_dir' => ROOT_DIR . "/" . Env::get('aliyun.img_local_save_path') . "/{$file_dir}",
    );
}
    
/**
 * 防止变量未设置报错的赋值
 *
 * 已废弃
 *
 * @param $value
 * @param  $default
 * @return string
 */
function safeValue($value, $default = '') {
    return $res = $value??$default;
}

/**
 * 接收web文件上传到oss
 * @param \think\File $file 文件上传接收的file对象
 * @param bool $is_internal 是否内网传输
 * @param int $compress 如果是图片，可设置图片压缩比 1-100 100为不压缩
 * @param int $max_width 如果是图片，可设置最大宽度，不处理可设置为0
 * @param int $thumb_width 设置缩略图宽度,生成缩略图,null不生成
 * @return array file_dir:保存目录，file_name:文件名
 * @throws \OSS\Core\OssException
 */
function web_upload_oss(File $file, $is_internal = false, $compress = 100, $max_width = 1280, $thumb_width = null)
{
    $result = array('result' => 1);
    $file_info = generate_oss_info($file->getInfo('name'));
    $save_file_full_path = '';
    $save_file_name = '';
    if (!is_dir($file_info['local_file_dir'])) {
        mmkdir($file_info['local_file_dir']);
    }
    if ($compress < 100 || $max_width > 0) {
        $save_file_full_path = $file_info['local_file_dir'];
        $save_file_name = $file_info['name'] . '.png';
        $save_file_thumb_name = $file_info['name'] . 'sm.png';
        $editor = Grafika::createEditor();
        $img_obj = null;
        $editor->open($img_obj, $file->getInfo('tmp_name'));
        //宽度超过max_width缩放
        if ($img_obj->getWidth() > $max_width) {
            $editor->resizeExactWidth($img_obj, $max_width);
        }
        $editor->save($img_obj, $save_file_full_path . '/' . $save_file_name, 'png',100, true, 0777);
        if ($thumb_width > 0) {//上传保存缩略图
            $editor->resizeExactWidth($img_obj, $thumb_width);
            $editor->save($img_obj, $save_file_full_path . '/' . $save_file_thumb_name, 'png', 100, true, 0777);
            if (Env::get('aliyun.oss_upload') && !upload_oss($file_info['file_dir'] . '/' . $save_file_thumb_name, $save_file_full_path . '/' . $save_file_thumb_name)) {
                $result['result'] = 0;
            } else {
                if (!Env::get('aliyun.img_local_save_copy')) {
                    @unlink($save_file_full_path . '/' . $save_file_thumb_name);
                }
            }
        }
    } else {
        $save_file_full_path = $file_info['local_file_dir'];
        $save_file_name = $file_info['file_name'];
        $file->move($save_file_full_path, $save_file_name);
    }
    if (Env::get('aliyun.oss_upload') && !upload_oss($file_info['file_dir'] . '/' . $save_file_name, $save_file_full_path . '/' . $save_file_name)) {
        $result['result'] = 0;
    } else {
        if (!Env::get('aliyun.img_local_save_copy')) {
            @unlink($save_file_full_path . '/' . $save_file_name);
        }
        $result = array_merge($result, [
            'file_dir' => $file_info['file_dir'],
            'file_name' => $save_file_name,
            'name' => $file_info['name'],
        ]);
    }
    return $result;
}

/**
 * 上传文件到oss
 * @param $save_object
 * @param $local_file
 * @param bool $is_internal
 * @throws \OSS\Core\OssException
 */
function upload_oss($save_object, $local_file, $is_internal = false)
{
    $accessKeyId = Env::get('aliyun.oss_access_id');
    $accessKeySecret = Env::get('aliyun.oss_access_key');
    $endpoint = !$is_internal ? Env::get('aliyun.oss_endpoint') : Env::get('aliyun.oss_internal_endpoint');
    $bucket = Env::get('aliyun.oss_bucket');
    //var_dump($accessKeyId,$accessKeySecret,$endpoint,$bucket);die;
    try {
        $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint);
        $upload_info = $ossClient->uploadFile($bucket, $save_object, $local_file);
        $result = $upload_info['info']['http_code'] == 200 ? true : false;
        Log::info("oss upload is_internal={$is_internal} local_file={$local_file} save_object={$save_object} result={$result}");
        if (!$result) {
            Log::info("oss upload error=" . var_export($upload_info, true));
        }
    } catch (\OSS\Core\OssException $e) {
        $result = false;
        Log::info("oss upload error={$e->getMessage()}");
    }
    return (int)$result;
}

/**
 * 后台获取本地图片文件显示地址
 * @param $filepath
 * @return string
 */
function get_local_img_preview_url($filepath)
{
    return "/img/preview?file={$filepath}";
}

function get_local_thumb_img_preview_url($filepath)
{
    $pos = strrpos($filepath, '.');
    $filepath = substr($filepath, 0, $pos) . 'sm' . substr($filepath, $pos);
    return "/img/preview?file={$filepath}";
}

/**
 * @param $file_path
 * @return mixed
 */
function get_mime_type($file_path)
{
    $finfo = finfo_open(FILEINFO_MIME);
    $mimetype = finfo_file($finfo, $file_path);
    finfo_close($finfo);
    return $mimetype;
}

/**
 *  * 是否是图片
 * @param $file_path
 * @return bool
 */
function is_img($file_path)
{
    return in_array(strtolower(get_extension($file_path)), array(
        'gif', 'jpg', 'jpeg', 'png', 'bmp', 'webp'
    ));
}


/*
* 生成二维码图片
*/
function qr_code_butler()
{
    $link = 'http://' . $_SERVER['HTTP_HOST'] . '/login';
    $sha1 = sha1($link);
    $qrcode_dir = __DIR__ . '/qrcode/' . substr($sha1, 0, 2) . '/' . substr($sha1, 2, 3) . '/';
    if (!file_exists($qrcode_dir)) mkdir($qrcode_dir, 0777, true);
    $file_name = $qrcode_dir . $sha1 . '.png';
    header('Content-Type: image/png');
    if (is_file($file_name)) {
        echo file_get_contents($file_name);
    } else {
        $qrCode = new QrCode($link);
        echo $qrCode->writeString();
        $qrCode->writeFile($file_name);
    }
    die();
}

//获取当前毫米时间戳
function microtime_float()
{
    list($usec, $sec) = explode(" ", microtime());
    return round(((float)$usec + (float)$sec)*1000);
}

/**
 * 生成提货码图片
 */
function create_pick_code()
{
    $pick_code = substr(microtime_float(),-8);
    $file_dir = date('Y/m/d', time()) . '/';
    $content = $pick_code;
    $sha1 = md5($content);
    $file_name = $sha1 . '.png';
    $qrCode = new QrCode($content);
    $file_path = './pickcode/' . $file_dir;
    if (!is_dir($file_path)) mkdir($file_path, 0777, true);
    $qrCode->writeFile($file_path . $file_name);
    if (!upload_oss($file_dir . $file_name, $file_path . $file_name)) {
        return false;
    }
    return [
        'name' => $sha1,
        'path' => $file_dir . $file_name,
        'pick_code' => $pick_code
    ];
}

/**  
* 二维数组，按键名排序
* 
* @author xionggan
* @param mixed $arr     被排序的数组
* @param mixed $keys    要参与排序的键名
* @param mixed $order   参与排序键名的排序方式 ASC DESC
* @return array
*/  
function sortArrayMulti(array &$arr, array $keys, array $order)
{
    //校验参数
    if (count($keys) == ($times = count($order))) {
        for ($i = 0, $j = 0; $j < $times; $i += 2, $j++) {
            foreach ($arr as $k => $v) {
                //原数组是否存在该字段
                if (isset($v[$keys[$j]])) {
                    /* $params[$i][] = $v[$keys[$j]];    
                    TODO 中文排序支持 */
                    $params[$i][] = iconv('UTF-8', 'GBK', $v[$keys[$j]]); 
                } else {
                    return false;
                }
            }
            if (strtoupper($order[$j]) == 'ASC') {
                $params[$i + 1] = SORT_ASC;
            } else {
                $params[$i + 1] = SORT_DESC;
            }
        }
        $params[] = &$arr;
        return call_user_func_array('array_multisort', $params);
    } else {
        return false;
    }
}

/**
 * 发送短信,主要用于验证码
 * @param string  $TemplateCode     短信模板编号
 * @param string  $send_tel         发送的手机号码
 * @param int     $TemplateParam    模块参数,为JSON格式
 * @return bool
 */
function send_sms($TemplateCode='',$send_tel='',$TemplateParam="")
{
    $yesno=false;
    if(empty($send_tel) || empty($TemplateCode) || empty($TemplateParam))
    {
        return $yesno;
    }
    $query_array['RegionId']       =   'cn-hangzhou';
    $query_array['PhoneNumbers']   =    $send_tel;
    $query_array['SignName']       =    '蜂乐购';
    $query_array['TemplateCode']   =    $TemplateCode;
    $query_array['TemplateParam']  =    $TemplateParam;
    AlibabaCloud::accessKeyClient(Env::get('aliyun.sms_access_id'),  Env::get('aliyun.sms_access_key'))
        ->regionId('cn-hangzhou')
        ->asGlobalClient();
    try {
        $result = AlibabaCloud::rpcRequest()
            ->product('Dysmsapi')
            ->scheme('https')
            ->version('2017-05-25')
            ->action('SendSms')
            ->method('POST')
            ->options([
                'query' => $query_array
            ])
            ->request();
        $result_array=$result->toArray();

        Log::info("sms:info:".print_r($result_array,1).$TemplateParam);
        if($result_array['Message']==="OK"){
            $yesno=true;
        }
    } catch (ClientException $e) {
        Log::info("sms:error:".$e->getErrorMessage(). PHP_EOL);
    } catch (ServerException $e) {
        Log::info("sms:error:".$e->getErrorMessage(). PHP_EOL);
    }
    return $yesno;
}

/**
 * 设置一天内不能发送两次短信
 * @param $tel
 * @param $type
 * @return bool
 */
function set_code($tel,$type){
    try {
        $redis = new \other\BaseRedis();
        /**
         * 判断是否设置了code
         */
        if ( $redis->get('type:' . $type . ':' . $tel))
        {
            $data=$redis->get('type:'.$type.':'.$tel);

            $data_time=strtotime(date('Y-m-d',$data));
            $now_time=strtotime(date('Y-m-d',time()));

            if (($now_time-$data_time)/(24*3600)<1)
            {
                return false;
            }else
            {
                $redis->set('type:' . $type . ':' . $tel, time());
                return true;
            }
        }else
        {
            $redis->set('type:' . $type . ':' . $tel, time());
            return true;
        }
    }catch (\other\BaseException $e)
    {
        Log::write($e->getMessage().",redis连接失败!","error");
    }
}